﻿package ru.volgogradetzzz.utils {
	
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	
	/**
	 * ...
	 * @author Volgogradetzzz
	 */
	public class Logger extends Sprite {
		
		public static const DEBUG:String = '#FFFFFF';
		public static const INFO:String = '#00FF00';
		public static const ERROR:String = '#FF0000';
		
		private const _LINE_NUMBER_WIDTH:uint = 30;
		private const _TF_LINE_NUMBER:TextField = new TextField();
		private const _TF:TextField = new TextField();
		
		private static var _instance:Logger;
		
		private var _h:uint = 400;
		private var _lineNumberBg:Shape = new Shape();
		private var _bg:Shape = new Shape();
		
		public static function getInstance():Logger {
			if (_instance == null){
				_instance = new Logger(SINGLETON_KEY);
			}
			
			return _instance;
		}
		
		public function Logger(checkKey:Object) {
			if (checkKey != SINGLETON_KEY){
				throw(new Error("Экземпляр Logger необходимо получать с помощью метода Logger.getInstance()."));
			}
			
			addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
			
			_lineNumberBg.graphics.beginFill(0x000000, 0.8);
			_lineNumberBg.graphics.drawRect(0, 0, _LINE_NUMBER_WIDTH, _h);
			_lineNumberBg.graphics.endFill();
			
			_bg.graphics.beginFill(0x000000, 0.6);
			_bg.graphics.drawRect(0, 0, 100, _h);
			_bg.graphics.endFill();
			_bg.x = _LINE_NUMBER_WIDTH;
			
			_TF_LINE_NUMBER.multiline = true;
			_TF_LINE_NUMBER.wordWrap = true;
			_TF_LINE_NUMBER.width = _LINE_NUMBER_WIDTH;
			_TF_LINE_NUMBER.defaultTextFormat = new TextFormat('Arial', 10, 0xC0C0C0, null, null, null, null, null, TextFormatAlign.RIGHT);
			_TF_LINE_NUMBER.selectable = false;
			_TF_LINE_NUMBER.height = _h;
			
			_TF.multiline = true;
			_TF.wordWrap = true;
			_TF.defaultTextFormat = new TextFormat('Arial', 10);
			_TF.x = _LINE_NUMBER_WIDTH;
			_TF.height = _h;
			_TF.addEventListener(Event.SCROLL, textScrollHandler);
			
			addChild(_lineNumberBg);
			addChild(_bg);
			addChild(_TF_LINE_NUMBER);
			addChild(_TF);
		}
		
		private function textScrollHandler(event:Event):void {
			_TF_LINE_NUMBER.scrollV = _TF.scrollV;
		}
		
		public function log(str:String, color:String = DEBUG):void {
			str = str.replace(/</g, '&lt;');
			str = str.replace(/>/g, '&gt;');
			
			_TF.htmlText += '<font color="' + color + '">' + str + '</font>\n';
			_TF.scrollV = _TF.numLines;
			
			_TF_LINE_NUMBER.text = '';
			for (var lineIndex:uint = 1, numLines:uint = _TF.numLines; lineIndex <= numLines; lineIndex++) {
				_TF_LINE_NUMBER.appendText(lineIndex + '\n');
			}
			
			_TF_LINE_NUMBER.scrollV = _TF.scrollV;
			
			trace(str);
		}
		
		private function addedToStageHandler(event:Event):void {
			y = stage.stageHeight - _h;
			_bg.width = stage.stageWidth - _LINE_NUMBER_WIDTH;
			_TF.width = _bg.width;
		}
	}
}

internal const SINGLETON_KEY:Object = {};